package logic

import (
	"common"
	"common/auth"
	"common/grpcx"
	"common/zapx"
	"errors"
	"gateway/internal/pb"
	"github.com/gin-gonic/gin"
	"time"
	"wrong"

	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

type ComicLogic struct {
	BaseLogicAbs
}

func NewComicLogic() *ComicLogic {
	logic := &ComicLogic{
		BaseLogicAbs{
			message: "",
		},
	}
	return logic
}

func (cl *ComicLogic) GetComicList(Title *string, NavigateId *int64, Page *int32, PerPage *int32) *pb.ComicListResponse {
	conn, err := grpc.Dial(
		common.ConsulSerUrl("comic"),
		grpc.WithTransportCredentials(insecure.NewCredentials()),
	)
	if err != nil {
		zapx.Logger.Error("[GetComicList]连接comic服务失败", zap.Error(err))
		return &pb.ComicListResponse{}
	}
	defer conn.Close()
	client := pb.NewComicClient(conn)
	ctx, cancel := common.WithTimeoutContext(time.Second * 2)
	defer cancel()
	res, err := client.ComicList(ctx, &pb.ComicListRequest{
		Title:      Title,
		Page:       Page,
		PerPage:    PerPage,
		NavigateId: NavigateId,
	})
	if err != nil {
		zapx.Logger.Error("[GetComicList]查询漫画失败", zap.Error(err))
		return &pb.ComicListResponse{}
	}
	return res
}

func (cl *ComicLogic) GetChapterByComicId(comicId int32, page *int32, perPage *int32) (res *pb.ChapterListResponse) {
	err := grpcx.NewNoCertConnWithCaller("comic", func(conn *grpc.ClientConn) error {
		client := pb.NewComicClient(conn)
		ctx, cancel := common.WithTimeoutContext(time.Second * 2)
		defer cancel()
		var e error
		res, e = client.ChapterList(ctx, &pb.ChapterListRequest{
			ComicId: comicId,
			Page:    page,
			PerPage: perPage,
		})
		if e != nil {
			return e
		}
		return nil
	})

	if err != nil {
		zapx.Logger.Error("[GetChapterByComicId]查询漫画章节失败", zap.Error(err))
	}

	return res
}

// GetResourceByChapterId 通过grpc获取漫画章节图片
func (cl *ComicLogic) GetResourceByChapterId(ginCtx *gin.Context, chapterId int32) (ret []string, err error) {
	ret = []string{}
	conn, err := grpc.Dial(
		common.ConsulSerUrl("comic"),
		grpc.WithTransportCredentials(insecure.NewCredentials()),
	)
	if err != nil {
		zapx.Logger.Error("[GetResourceByChapterId]连接comic服务失败", zap.Error(err))
		return []string{}, errors.New("系统内部错误")
	}
	defer conn.Close()
	comicClient := pb.NewComicClient(conn)
	ctx, cancel := common.WithMetaDataOutGoingTimeoutContext(time.Second*2, grpcx.GetUserMetaData(ginCtx))
	defer cancel()
	res, err := comicClient.Resource(ctx, &pb.ResourceRequest{
		ChapterId: chapterId,
	})
	if err != nil {
		zapx.Logger.Error("[GetResourceByChapterId]远程调用失败", zap.Error(err))
		return []string{}, err
	}
	ret = res.Image
	return
}

// GetComicDetail 获取漫画详情
func (cl *ComicLogic) GetComicDetail(ginCtx *gin.Context, comicId int64) (*pb.ComicEntity, error) {
	ctx, cancel := common.WithMetaDataOutGoingTimeoutContext(time.Second*2, grpcx.GetUserMetaData(ginCtx))
	defer cancel()
	conn, err := grpcx.NewNoCertConn("comic")
	if err != nil {
		zapx.Logger.Error("连接[comic]服务失败", zap.Error(err))
		return nil, wrong.GRPC_CONN_FAILED
	}
	defer conn.Close()
	client := pb.NewComicClient(conn)
	res, err := client.ComicDetail(ctx, &pb.ComicDetailRequest{
		ComicId: comicId,
	})
	if err != nil {
		return nil, grpcx.CovertGrpcError(err)
	}
	return res.ComicInfo, nil
}

// GetChapterDetail 获取章节详情
func (cl *ComicLogic) GetChapterDetail(ginCtx *gin.Context, chapterId int32) (*pb.ChapterEntity, error) {
	ctx, cancel := common.WithMetaDataOutGoingTimeoutContext(time.Second*2, grpcx.GetUserMetaData(ginCtx))
	defer cancel()
	conn, err := grpcx.NewNoCertConn("comic")
	if err != nil {
		zapx.Logger.Error("链接[comic]服务失败", zap.Error(err))
		return nil, errors.New("系统错误")
	}
	defer conn.Close()
	client := pb.NewComicClient(conn)
	res, err := client.GetChapterDetail(ctx, &pb.GetChapterDetailRequest{ChapterId: chapterId})
	if err != nil {
		return nil, err
	}
	return res.ChapterDetail, nil
}

// ComicLookFor 帮找漫画
func (cl *ComicLogic) ComicLookFor(auth *auth.AuthObject, title string, link *string) error {
	err := grpcx.NewNoCertConnWithCaller("comic", func(conn *grpc.ClientConn) error {
		caller := pb.NewComicClient(conn)
		ctx, cancel := common.WithMetaDataOutGoingTimeoutContext(time.Second*2, auth.GetGrpcAuthMetadata())
		defer cancel()
		_, err := caller.Find(ctx, &pb.FindRequest{
			Title: title,
			Link:  link,
		})
		return err
	})
	if err != nil {
		return grpcx.CovertGrpcError(err)
	}
	return nil
}
